"""
作者：Leagolas
日期：2024年06月12日
"""
import numpy as np
import pandas as pd


def daily_settlement(i, position_pd, recorded_position_type, options_data, futures_data, cash_change = False):
    if recorded_position_type[0] != 'none':

        today_date = position_pd.iloc[i]['交易日']
        yesterday_date = position_pd.iloc[i - 1]['交易日']
        call_option_code = position_pd.loc[i, 'call_option']
        put_option_code = position_pd.loc[i, 'put_option']

        today_call_options_price = \
        options_data[(options_data['交易代码'] == call_option_code) & (options_data['交易日'] == today_date)][
            '收盘价'].iloc[0]
        yesterday_call_options_price = \
        options_data[(options_data['交易代码'] == call_option_code) & (options_data['交易日'] == yesterday_date)][
            '收盘价'].iloc[0]
        today_put_options_price = \
        options_data[(options_data['交易代码'] == put_option_code) & (options_data['交易日'] == today_date)][
            '收盘价'].iloc[0]
        yesterday_put_options_price = \
        options_data[(options_data['交易代码'] == put_option_code) & (options_data['交易日'] == yesterday_date)][
            '收盘价'].iloc[0]
        options_price_diff = today_call_options_price + today_put_options_price - yesterday_call_options_price - yesterday_put_options_price

        today_futures_price = futures_data[futures_data['交易日'] == today_date]['收盘价'].iloc[0]
        yesterday_futures_price = futures_data[futures_data['交易日'] == yesterday_date]['收盘价'].iloc[0]
        futures_price_difference = today_futures_price - yesterday_futures_price

        if recorded_position_type[0] == 'long':
            position_pd.loc[i, 'cash_flow'] = position_pd.loc[i, 'futures_position'] * futures_price_difference
            position_pd.loc[i, 'cash'] = position_pd.loc[i - 1, 'cash'] + position_pd.loc[i, 'cash_flow']
            position_pd.loc[i, 'portfolio'] = position_pd.loc[i- 1 , 'portfolio'] + 10000 * options_price_diff

            if cash_change:
                position_pd.loc[i, 'cash_flow'] = position_pd.loc[i, 'cash_flow'] + position_pd.loc[i, 'portfolio']
                position_pd.loc[i, 'cash'] = position_pd.loc[i, 'cash'] + position_pd.loc[i, 'portfolio']
                position_pd.loc[i, 'portfolio'] = 0




        elif recorded_position_type[0] == 'short':
            position_pd.loc[i, 'cash_flow'] = position_pd.loc[i, 'futures_position'] * futures_price_difference
            position_pd.loc[i, 'cash'] = position_pd.loc[i - 1, 'cash'] + position_pd.loc[i, 'cash_flow']
            position_pd.loc[i, 'portfolio'] = position_pd.loc[i - 1, 'portfolio'] - 10000 * options_price_diff

            if cash_change:
                position_pd.loc[i, 'cash_flow'] = position_pd.loc[i, 'cash_flow'] + position_pd.loc[i, 'portfolio']
                position_pd.loc[i, 'cash'] = position_pd.loc[i, 'cash'] + position_pd.loc[i, 'portfolio']
                position_pd.loc[i, 'portfolio'] = 0







def long_volatility(i ,recorded_position_type, current_month, options_data, sse50ETF_data, futures_data, position_pd):
    recorded_position_type[0] = 'long'
    tradingdate = position_pd.iloc[i]['交易日']

    options_list = options_data[options_data['交易日'] == tradingdate]
    options_list = options_list[options_list["交易代码"].str[7:11].astype(int) > int(current_month[0])]
    call_options_list = options_list[options_list["交易代码"].str.contains('C', na=False)]
    put_options_list = options_list[options_list["交易代码"].str.contains('P', na=False)]


    etf_price = float(sse50ETF_data[sse50ETF_data['交易日'] == tradingdate]['收盘价'].iloc[0])
    futures_price = float(futures_data[futures_data['交易日'] == tradingdate]['收盘价'].iloc[0])
    closet_call_option = call_options_list.loc[(call_options_list['行权价'] - etf_price).abs().idxmin()]
    closet_put_option = put_options_list.loc[(put_options_list['行权价'] - etf_price).abs().idxmin()]

    options_delta_10000 = 10000 * (closet_call_option['Delta'] + closet_put_option['Delta'])

    futures_position = round(options_delta_10000) * (-1)

    position_pd.loc[i,'position_type'] = 'long'
    position_pd.loc[i,'call_option'] = closet_call_option['交易代码']
    position_pd.loc[i,'put_option'] = closet_put_option['交易代码']
    position_pd.loc[i,'futures_position'] = futures_position
    position_pd.loc[i, 'cash_flow'] = -10000 * (closet_call_option['收盘价'] + closet_put_option['收盘价'])
    position_pd.loc[i, 'cash'] = position_pd.loc[i - 1, 'cash'] + position_pd.loc[i, 'cash_flow']
    position_pd.loc[i, 'portfolio'] = 10000 * (closet_call_option['收盘价'] + closet_put_option['收盘价'])

    return 0

def short_volatility(i ,recorded_position_type, current_month, options_data, sse50ETF_data, futures_data,position_pd):
    recorded_position_type[0] = 'short'
    tradingdate = position_pd.iloc[i]['交易日']

    options_list = options_data[options_data['交易日'] == tradingdate]
    options_list = options_list[options_list["交易代码"].str[7:11].astype(int) > int(current_month[0])]
    call_options_list = options_list[options_list["交易代码"].str.contains('C', na=False)]
    put_options_list = options_list[options_list["交易代码"].str.contains('P', na=False)]

    etf_price = float(sse50ETF_data[sse50ETF_data['交易日'] == tradingdate]['收盘价'].iloc[0])
    futures_price = float(futures_data[futures_data['交易日'] == tradingdate]['收盘价'].iloc[0])
    closet_call_option = call_options_list.loc[(call_options_list['行权价'] - etf_price).abs().idxmin()]
    closet_put_option = put_options_list.loc[(put_options_list['行权价'] - etf_price).abs().idxmin()]

    options_delta_10000 = -10000 * (closet_call_option['Delta'] + closet_put_option['Delta'])

    futures_position = round(options_delta_10000) * (-1)

    position_pd.loc[i,'position_type'] = 'short'
    position_pd.loc[i,'call_option'] = closet_call_option['交易代码']
    position_pd.loc[i,'put_option'] = closet_put_option['交易代码']
    position_pd.loc[i,'futures_position'] = futures_position
    position_pd.loc[i, 'cash_flow'] = 10000 * (closet_call_option['收盘价'] + closet_put_option['收盘价'])
    position_pd.loc[i, 'cash'] =  position_pd.loc[i - 1, 'cash'] + position_pd.loc[i, 'cash_flow']
    position_pd.loc[i, 'portfolio'] = -10000 * (closet_call_option['收盘价'] + closet_put_option['收盘价'])

    return 0

def close_position(i, position_pd, recorded_position_type, options_data, futures_data):
    daily_settlement(i, position_pd, recorded_position_type, options_data, futures_data, cash_change=True)
    position_pd.loc[i, 'position_type'] = pd.NA
    position_pd.loc[i, 'call_option'] = pd.NA
    position_pd.loc[i, 'put_option'] = pd.NA
    position_pd.loc[i, 'futures_position'] = pd.NA
    recorded_position_type[0] = 'none'

